/* * @(#)ProgressMonitor.java 1.10 98/02/02 * * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * */ package com.sun.java.swing; import java.io.*; import java.awt.Frame; import java.awt.Component; /** A class to monitor the progress of some operation. If it looks * like it will take a while, a progress dialog will be popped up. * When the ProgressMonitor is created it is given a numeric range and a descriptive * string. As the operation progresses, call the setProgress method * to indicate how far along the [min,max] range the operation is. * Initially, there is no ProgressDialog. After the first millisToDecideToPopup * milliseconds (default 500) the progress monitor will predict how long * the operation will take. If it is longer than millisToPopup (default 2000, * 2 seconds) a ProgressDialog will be popped up. *

* From time to time, when the Dialog box is visible, the progress bar will * be updated when setProgress is called. setProgress won't always update * the progress bar, it will only be done if the amount of progress is * visibly significant. *

* @see ProgressMonitorInputStream * @author James Gosling */ public class ProgressMonitor { private int millisToDecideToPopup = 500; private int millisToPopup = 2000; private int min, max, v, lastDisp; private int reportDelta; private ProgressMonitor root; private JDialog dialog; private JOptionPane pane; private JProgressBar myBar; private JLabel noteLabel; private Component parentComponent; private String note; private Object message; private long T0; /** @param parentComponent the parent component for the dialog box @param message a descriptive message that will be shown to the user to indicate what operation is being monitored. This does not change as the operation progresses. See the message parameters to methods in JOptionsPane for the range of values. @param note a short note describing the state of the operation. As the operation progresses, you can call setNote to change the note displayed. This is used, for example, in operations that iterate through a list of files to show the name of the file being processes. If note is initially null, there will be no note line in the dialog box and setNote will be ineffective @param min the lower bound of the range @param max the upper bound of the range @see JDialog @see JOptionPane */ public ProgressMonitor(Component parentComponent, Object message, String note, int min, int max) { this(parentComponent,message,note,min,max,null); } /** Some day I want to put in groups of progress monitors... */ private ProgressMonitor(Component parentComponent, Object message, String note, int min, int max, ProgressMonitor group) { this.min = min; this.max = max; this.parentComponent = parentComponent; reportDelta = (max-min)/100; if (reportDelta<1) reportDelta = 1; v = min; this.message = message; this.note = note; if (group != null) { root = group.root != null ? group.root : group; T0 = root.T0; dialog = root.dialog; } else { T0 = System.currentTimeMillis(); } } private static class ProgressOptionPane extends JOptionPane { ProgressOptionPane(Object messageList) { super(messageList, JOptionPane.INFORMATION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, null); } public int getMaxCharactersPerLineCount() { return 60; } }; /** Indicate the progress of the operation being monitored. */ public void setProgress(int nv) { v = nv; if (nv >= max) close(); else if (nv>=lastDisp+reportDelta) { lastDisp = nv; if(myBar != null) myBar.setValue(nv); else { long T = System.currentTimeMillis(); long dT = (int)(T-T0); if (dT >= millisToDecideToPopup) { int predictedCompletionTime; if (nv>min) predictedCompletionTime = (int)((long)dT*(max-min)/(nv-min)); else predictedCompletionTime = millisToPopup; if (predictedCompletionTime>=millisToPopup) { myBar = new JProgressBar(); myBar.setMinimum(min); myBar.setMaximum(max); myBar.setValue(nv); if (note != null) noteLabel = new JLabel(note); pane = new ProgressOptionPane(new Object[]{message, noteLabel, myBar}); dialog = pane.createDialog(parentComponent, "Progress..."); dialog.setModal(false); dialog.show(); } } } } } /** Indicate that the operation is complete. This happens automatically * when the value set by setProgress is >= max, but it may be called * earlier if the operation ends early. */ public void close() { if (dialog != null) { dialog.setVisible(false); dialog.dispose(); dialog = null; pane = null; myBar = null; } } public int getMinimum() { return min; } public void setMinimum(int m) { min = m; } public int getMaximum() { return max; } public void setMaximum(int m) { max = m; } /** Returns true if the user does some UI action to cancel this operation. * (like hitting the Cancel button on the progress dialog). */ public boolean isCanceled() { if (pane == null) return false; Object v = pane.getValue(); return v!=null && v instanceof Integer && ((Integer)v).intValue()==2; } public void setMillisToDecideToPopup(int millisToDecideToPopup) { this.millisToDecideToPopup = millisToDecideToPopup; } public int getMillisToDecideToPopup() { return millisToDecideToPopup; } public void setMillisToPopup(int millisToPopup) { this.millisToPopup = millisToPopup; } public int getMillisToPopup() { return millisToPopup; } public void setNote(String note) { this.note = note; if (noteLabel != null) noteLabel.setText(note); } public String getNote() { return note; } }